package com.itheima.protocol.disruptor;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.SequenceBarrier;
import com.lmax.disruptor.WaitStrategy;
import com.lmax.disruptor.WorkerPool;
import com.lmax.disruptor.YieldingWaitStrategy;
import com.lmax.disruptor.dsl.ProducerType;

public class UtranUuEventProducerSingleton {

    private static final WaitStrategy YIELDING_WAIT = new YieldingWaitStrategy();
    int ringBufferSize = 1024 * 1024;
    RingBuffer<UtranUuDisruptorEvent> ringBuffer;

    private static ThreadLocal<UtranUuEventProducerWithTranslator> threadLocal = new ThreadLocal<UtranUuEventProducerWithTranslator>();

    private static class SingletonHolder {

        public static UtranUuEventProducerSingleton instance = new UtranUuEventProducerSingleton();
    }

    public static UtranUuEventProducerSingleton newInstance() {

        return SingletonHolder.instance;
    }

    private UtranUuEventProducerSingleton() {

        Executor executor = Executors.newCachedThreadPool();
        EventFactory<UtranUuDisruptorEvent> factory = new EventFactory<UtranUuDisruptorEvent>() {
            @Override
            public UtranUuDisruptorEvent newInstance() {

                return new UtranUuDisruptorEvent();
            }
        };

        ringBuffer = RingBuffer.create(ProducerType.MULTI, factory, ringBufferSize, YIELDING_WAIT);
        SequenceBarrier barriers = ringBuffer.newBarrier();

        UtranUuEventDisruptorHandler[] consumers = new UtranUuEventDisruptorHandler[3];
        for (int i = 0; i < consumers.length; i++) {
            consumers[i] = new UtranUuEventDisruptorHandler();
        }
        WorkerPool<UtranUuDisruptorEvent> workerPool = new WorkerPool<UtranUuDisruptorEvent>(ringBuffer, barriers,
                new IntEventExceptionHandler(), consumers);

        ringBuffer.addGatingSequences(workerPool.getWorkerSequences());
        workerPool.start(executor);

    }

    public void saveProducerData(final Object RemoveMap, final String clearMapKey) {

        if (threadLocal.get() == null) {
            UtranUuEventProducerWithTranslator producer = new UtranUuEventProducerWithTranslator(ringBuffer);
            threadLocal.set(producer);
        }
        setData(RemoveMap, clearMapKey);

    }

    public void setData(Object RemoveMap, String clearMapKey) {

        UtranUuDisruptorEvent uuExtendDisruptorEvent = new UtranUuDisruptorEvent();
        uuExtendDisruptorEvent.setClearTime(System.currentTimeMillis());
        uuExtendDisruptorEvent.setCkearMapKey(clearMapKey);
        uuExtendDisruptorEvent.setJobRunRemoveMap(RemoveMap);
        threadLocal.get().onData(uuExtendDisruptorEvent);
    }
}
